package ar.edu.utn.frsf.cidisi.upcolbpip.modelgeneration.generator;

import java.util.HashMap;
import java.util.List;
import java.util.Random;

import ar.edu.utn.frsf.cidisi.upcolbpip.UPColBPIPModel;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.BusinessMessage;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Condition;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.ControlFlowSegment;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionPath;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocol;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionprotocolsFactory;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.MultipleInstance;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Termination;

public class CompleteModel {

	private UPColBPIPModel upcolbpipModel;
		
	private int maxNodes;
	private int minNodes;
	private int maxNestingLevel;
	private int minNestingLevel;
	private int maxSequence;
	private int minSequence;
	private int maxInteractionPath;
	private int minInteractionPath;
	private int maxHandlers;
	private int minHandlers;
	private int maxInteractionProtocols;
	
	private int constructs;
	
	static public String XOR = "xor";
	static public String AND = "and";
	static public String OR = "or";
	static public String LOOP_WHILE = "loop-while";
	static public String LOOP_UNTIL = "loop-until";
	static public String CANCEL = "cancel";
	static public String EXCEPTION = "exception";
	static public String TERMINATION = "termination";
	static public String MULTIPLE_INSTANCES = "multiple instances";
	static public String BUSINESS_MESSAGE = "business message";
	static public String INTERACTION_PATH = "interaction path";
	

	
	/**
	 * Stores the number of elements of a currentIProt.- 
	 */
	private int nodesCount = 0;
	
	/**
	 * A map where the key is an interaction protocol and the value is the number of nodes of such interaction protocol.- 
	 */
	private HashMap<String, Integer> iProtNodesCountMap = new HashMap<String, Integer>();
	
	public CompleteModel() {
		
//		upcolbpipModel = UpcolbpipFactory.eINSTANCE.createUPColBPIPModel();
//		B2BCollaboration b2bCollaboration = B2bcollaborationsFactory.eINSTANCE.createB2BCollaboration();
//
//		upcolbpipModel.setB2bCollaboration(b2bCollaboration);
//
//		CollaborativeBusinessProcess collaborativeBusinessProcess =  CollaborativebusinessprocessesFactory.eINSTANCE.createCollaborativeBusinessProcess();
//		b2bCollaboration.getProcesses().add( collaborativeBusinessProcess );

	}
	
	public CompleteModel(UPColBPIPModel upcolbpipModel, Experiment experiment) {
		
		this.upcolbpipModel = upcolbpipModel;
		
		minSequence=experiment.getMinSequence(); maxSequence=experiment.getMaxSequence(); 
		minInteractionPath=experiment.getMinInteractionPath(); maxInteractionPath=experiment.getMaxInteractionPath();
		minHandlers=experiment.getMinHandlers(); maxHandlers=experiment.getMaxHandlers();
		minNodes = experiment.getMinNodes(); maxNodes = experiment.getMaxNodes();
		minNestingLevel = experiment.getMinNestingLevel(); maxNestingLevel=experiment.getMaxNestingLevel();
		
		
		maxInteractionProtocols = experiment.getMaxInteractionProtocols();

	}

	
	public UPColBPIPModel getModelUpcolbpip() {
		return upcolbpipModel;
	}
	
	
	public void completeInteractionProtocols(){
		int iProtId = upcolbpipModel.getB2bCollaboration().getProcesses().get(0).getInteractionProtocols().size() + 1;
		for (int i=0;i<iProtId-1;i++){

			completeInteractionProtocol(upcolbpipModel.getB2bCollaboration().getProcesses().get(0).getInteractionProtocols().get(i));
			
		}
	}
	
	
	private void completeInteractionProtocol(InteractionProtocol iProt) {
		
		List<InteractionProtocolElement> elements = iProt.getIpElement();
		
		for (InteractionProtocolElement ipElem:elements) {
			completeInteractionPath(ipElem);
			
		}
		
		iProtNodesCountMap.put(iProt.getName(), nodesCount);
		
	}
	

	public void completeInteractionPath(InteractionProtocolElement ipElem) {
	
		if (!(ipElem instanceof Termination || ipElem instanceof BusinessMessage)){
			
			if (ipElem instanceof MultipleInstance){  // Creates a condition with the number of multiple instances
			
				InteractionPath iPath = ((MultipleInstance)ipElem).getInteractionPath().get(0);
				
				Random rIP = new Random();
				int ips = minInteractionPath + rIP.nextInt(maxInteractionPath-minInteractionPath);
				
				Condition cond = InteractionprotocolsFactory.eINSTANCE.createCondition();
				cond.setConditionExpression(""+ips);
				
				iPath.setGuard(cond);
				
			}
			
			List<InteractionPath> iPaths = ((ControlFlowSegment)ipElem).getInteractionPath();
			for (InteractionPath iPath:iPaths){
				
				for (InteractionProtocolElement elem:iPath.getElement()) {
					completeInteractionPath(elem);
				}
				
			}
			
		}

	}
		
	
	public int getNodesCount(InteractionProtocol ip){
		return iProtNodesCountMap.get(ip).intValue();
	}
	
}
